package com.projectbox.utility.impl;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.projectbox.model.Project;
import com.projectbox.model.Resource;
import com.projectbox.utility.ResourceStorageUtility;

public class FileResourceStorageUtility implements ResourceStorageUtility {
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	//private final String path = "/home/ec2-user/projectbox/";
	private final String path = "C:/projectbox/";

	public byte[] getResourceFile(Resource resource) {
		logger.debug(this.path + resource.getPid() + "/" + resetResourceName(resource.getFid(),resource.getName()));
		File file = new File(this.path + resource.getPid() + "/" + resetResourceName(resource.getFid(),resource.getName()));
		byte[] result = new byte[(int) file.length()];
		try {
			InputStream input = null;
			try {
				int totalBytesRead = 0;
				input = new BufferedInputStream(new FileInputStream(file));
				while (totalBytesRead < result.length) {
					int bytesRemaining = result.length - totalBytesRead;
					// input.read() returns -1, 0, or more :
					int bytesRead = input.read(result, totalBytesRead,
							bytesRemaining);
					if (bytesRead > 0) {
						totalBytesRead = totalBytesRead + bytesRead;
					}
				}				
				logger.debug("Num bytes read: " + totalBytesRead);
			} finally {
				logger.debug("Closing input stream.");
				input.close();
			}
		} catch (FileNotFoundException ex) {
			logger.debug("File not found.");
		} catch (IOException ex) {
			logger.debug("IOexception");
		}
		return result;
	}
	
	public void saveResource(Resource resource){
		
		File file;
		FileOutputStream fop = null;
		try {
			byte [] data = resource.getFile();
			logger.debug(this.path +  resource.getPid() + "/" + resetResourceName(resource.getFid(),resource.getName()));
			file = new File(this.path + resource.getPid() + "/" + resetResourceName(resource.getFid(),resource.getName()));
			fop = new FileOutputStream(file);
			fop.write(data);
			fop.flush();
			fop.close();
		} catch (IOException e) {
			logger.debug("saveResource: " + e.getMessage());
		}finally {
			try {
				if (fop != null) {
					fop.close();
				}
			} catch (IOException e) {
				logger.error("saveResource error in try: " + e.getMessage());
			}
		}				
	}
	
	public void deleteResource(Resource resource){

		logger.debug(this.path + resource.getPid() + "/" + resetResourceName(resource.getFid(),resource.getName()));
		File deleteFile = new File(this.path + resource.getPid() + "/" + resetResourceName(resource.getFid(),resource.getName()));
		if(deleteFile.delete()) {
			logger.debug("Successfully delete file");
		} else {
			//TODO UI should show errors
			logger.debug("Unsuccessfully delete file");
		}
	}
	
	public void deleteProjectDirectory(Project project){
		logger.debug("delete project directory " + project.getName() + " id: " + project.getId());
		
		File dir = new File (path + project.getId());
		if(dir.isDirectory() && dir.list().length == 0){
			dir.delete();
		} else{			 
 		   //list all the directory contents
     	   String files[] = dir.list();

     	   for (String temp : files) {
     		  File fileDelete = new File(dir, temp);
     		  fileDelete.delete();
     	   }
     	  dir.delete();
 		}
	    // The directory is now empty so delete it
	}
	
	public void createProjectDirectory(Long id) {
		logger.debug("create folder");
		try {
			boolean success = (new File(path + id)).mkdir();
			if (success) {
				logger.debug("Directory: " + id + " created");
			} else {
				logger.debug("it's not working");
			}

		} catch (Exception e) {// Catch exception if any
			logger.error("Error: " + e.getMessage());
		}
	}
	
	public void renameResource(Resource resource, String newName){
		Long fid = resource.getFid();
		String oldName = resource.getName();
		logger.debug("old "+ oldName + "new" + newName);
		File oldFile = new File(this.path + resource.getPid() + "/" + resetResourceName(fid,oldName));
		File newFile = new File(this.path + resource.getPid() + "/" + resetResourceName(fid,newName));
		
		boolean success = oldFile.renameTo(newFile);
		if (!success) {
		    // File was not successfully renamed
			logger.debug("not successful");
		} else 
			logger.debug("successful");
	}
	
	
	/**
	 * Helper method
	 */
	
	private String resetResourceName(Long fid, String rname){		
		logger.debug("fid" + fid + "rname " + rname);
		DecimalFormat myFormatter = new DecimalFormat("00000000000");
		
		String name = myFormatter.format(fid) + rname;
		
		logger.debug("reset name; " + name);
		
		return name;
	}
}
